package org.jspar.model;

import org.jspar.Constants;
import org.jspar.Options;


public class Utility {
	
	public static void addinout(String name, int i, int j) {
		throw new RuntimeException("addinout not completed");
	}

	public static void add_xc_term(String type, String pinName, String netName, int i) {
		
	}

	public static void adddelay(int delayTime) {
		throw new RuntimeException("not completed");
	}
	
	public static void addpositions(Module module, int incount,
			int inoutcount, int outcount) {
		boolean adjustTerminals = false;
		//int type = AsgModule.validate(module.type());
		int spacesPerPin = /*type == BLOCK || type == DONT_KNOW ?
				Constants.BLOCK_SPACES_PER_PIN
				: */ Constants.SPACES_PER_PIN;
		if (Options.getDefault().computeAspectRatios) {
			/* Might need to resize the bloody icon if its too bloody small. */
			int width = module.width();
			int height = module.height();
			if (inoutcount > module.width() / spacesPerPin) {
				/* the default iconsize won't cut it. This will fail in screwey sits. */
				width = Constants.SPACES_PER_PIN * inoutcount;
				adjustTerminals = true;
			}
			if (incount > module.height() / spacesPerPin
					|| outcount > module.height() / spacesPerPin) {
				/* the default iconsize won't cut it */
				height = spacesPerPin * Math.max(incount, outcount);
				adjustTerminals = true;
			}
			module.setSize(width, height);

			/* Check to see if there is wasted terminal space: (Icon is too big) */
			if (module.height() / spacesPerPin > Math.max(incount + 1, outcount + 1)
					|| module.width() / Constants.SPACES_PER_PIN > inoutcount + 1) {
				adjustTerminals = true;
			}
			if ((adjust_icon_size(module, Math.max(incount, outcount), inoutcount))
					|| adjustTerminals) {
				/* now reset all terminal positions to reflect this: */
				reposition_all_terminals(module, incount, inoutcount, outcount, spacesPerPin);
			}
		}
	}

	public static void fix_pin_position(Module module, String netName, int x, int y) {
		throw new RuntimeException("not completed");
	}

	public static void reset_default_icon_size(Module module, int x, int y) {
		throw new RuntimeException("not completed");
	}
	
	public static boolean adjust_icon_size(Module m, int vTerminals, int hTerminals) {
		throw new RuntimeException("not completed");
		/*int mType = AsgModule.validate(m.type());
		int mX = m.width();
		int mY = m.height();
		if (mType == AsgModule.BLOCK || mType == AsgModule.DONT_KNOW) {
			if (m.width() / m.height() < 3) {
				
				if (m.width() >= 2 * Constants.ICON_SIZE
						&& m.height() / 3 >= vTerminals * 2)
					m.setXSize(m.height() / 3);
				else if (m.height() / 2 >= vTerminals * 2)
					m.setXSize(m.height() / 2);
				
			} else if (m.height() / m.width() < 3) {
				
				if ((m.height() >= 2 * Constants.ICON_SIZE)
						&& (m.width() / 3 >= hTerminals * 2))
					m.setYSize(m.width() / 3);
				else if (m.width() / 2 >= hTerminals * 2)
					m.setYSize(m.width() / 2);
			}
			if ((m.width() != mX) || (m.height() != mY))
				return true;
		}
		return false;*/
	}
	
	public static void reposition_all_terminals(Module m, int incount, int inoutcount,
			int outcount, int spacesPerPin) {
		int INindex = 0;
		int INOUTindex = 0;
		int OUTindex = 0;

		for (Terminal t : m.terminals()) {
			switch (t.type().value()) {
			case Direction.IN_VALUE:
				t.setPosition(-1, relative_term_location(INindex++, incount, m.height(),
						spacesPerPin));
				break;

			case Direction.INOUT_VALUE:
				t.setPosition(relative_term_location(INOUTindex++, inoutcount, m
						.width(), spacesPerPin), m.height() + 1);
				break;

			case Direction.OUT_VALUE:
				t.setPosition(m.width() + 1, relative_term_location(OUTindex++, outcount, m.height(),
						spacesPerPin));
				break;
			}
		}
	}
	
	public static int relative_term_location(int termNo, int termsOnEdge,
			int edgeLength, int spacesPerPin) {
		
		int offset, space = edgeLength / (termsOnEdge + 1);

		if (termsOnEdge > edgeLength)
			return (termNo);
		
		if (termsOnEdge == edgeLength)
			return (termNo + 1);
		
		if (termNo > termsOnEdge)
			return (termNo); /* Problem !! */
		
		if (termsOnEdge <= 3) {
			switch (termsOnEdge) {
			case 1:
				return (edgeLength / 2);
			case 2:
				if (termNo == 0)
					return (space);
				return (edgeLength - space);
			default:
			case 3:
				switch (termNo) {
				case 0:
					return (edgeLength - space);
				case 1:
					return (edgeLength / 2);
				default:
				case 2:
					return (space);
				}
			}
		}
		/*
		 * Space things out evenly via spacesPerPin (used to set <edgeLength>)
		 */
		space = edgeLength / termsOnEdge;
		offset = (edgeLength - (termsOnEdge * space) + space) / 2;

		if (offset < 0)
			offset = 0;

		if ((termsOnEdge > edgeLength / spacesPerPin)
				&& (termNo > termsOnEdge / spacesPerPin)) { /* Overlap... */
			/* This should never be an important result - see "addpositions" */
			return ((termNo - termsOnEdge / spacesPerPin) * space);
		}
		return ((termNo * space) + offset);
	}

}
